package com.echovin.esb.gateway.oauth2.locator;

import com.echovin.esb.gateway.oauth2.model.PermissionAndRole;
import com.echovin.esb.gateway.oauth2.service.PermissionAndRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 资源加载器
 * @author dym
 * @date 2019/12/17
 */
@Slf4j
@Component
public class ResourceLocator {

    private Map<String, List<String>> resourceMap = new ConcurrentHashMap<>();

    private PathMatcher urlMatcher = new AntPathMatcher();
    @Autowired
    public PermissionAndRoleService permissionAndRoleService;

    public ResourceLocator() {
    }

    /**
     * 清空缓存并刷新
     */
    public void refresh() {
        this.resourceMap.clear();
        this.resourceMap.putAll(this.loadResourceDefine());
    }

    /**
     * 匹配url
     * @param urls
     * @param url
     * @return
     */
    public boolean matchUrl(String[] urls, String url) {
        if (urls == null || url == null) {
            return false;
        }
        for (int i = 0; i < urls.length; i++) {
            String resURL = urls[i];
            if (this.urlMatcher.match(resURL, url)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 拿到该url拥有权限的角色ids
     * @param url
     * @return
     * @throws IllegalArgumentException
     */
    public List<String> getResource(String url) throws IllegalArgumentException {
        return this.getAttributes(url);
    }

    /**
     * 匹配url，返回拥有访问该url权限的角色ids
     * @param url
     * @return
     * @throws IllegalArgumentException
     */
    private List<String> getAttributes(String url) throws IllegalArgumentException {
        this.refresh();
        Iterator ite = resourceMap.keySet().iterator();

        String resURL;
        do {
            if (!ite.hasNext()) {
                return null;
            }

            resURL = (String)ite.next();
        } while(!"/**".equals(resURL) && !"**".equals(resURL) && !this.urlMatcher.match(resURL, url));

        return (List)resourceMap.get(resURL);
    }

    /**
     * 调用service查询所有的资源与权限（角色）对应关系，组装{url：[ids]}
     */
    private Map<String, List<String>> loadResourceDefine() {
        Map<String, List<String>> map = new ConcurrentHashMap<>();
        try {
            // 查询所有接口
            List<PermissionAndRole> resourceList = this.permissionAndRoleService.getAllInterface();
            if (resourceList == null) {
                return map;
            }

            Iterator var3 = resourceList.iterator();
            while(var3.hasNext()) {
                PermissionAndRole resource = (PermissionAndRole)var3.next();
                List<String> atts = map.get(resource.getURL());
                if (atts == null) {
                    atts = new ArrayList();
                }
                if (!atts.contains(resource.getRoleId())) {
                    atts.add(resource.getRoleId());
                }
                map.put(resource.getURL(), atts);
            }

        } catch (Exception e) {
            log.error("加载动态权限错误:{}", e);
        }

        if (log.isDebugEnabled()) {
            log.debug("########资源与权限（角色）对应关系为{}", map);
        }
        return map;
    }

}
